<?php
	// No direct access to this file
	defined('_JEXEC') or die('Restricted access');

	require_once("xlsxreader.php");
	require_once(JPATH_COMPONENT_SITE . '/helpers/LanguageHelper.php');

	/**
	 * Created by JetBrains PhpStorm.
	 * User: martin.maliska
	 * Date: 20.2.2012
	 * Time: 21:16
	 * To change this template use File | Settings | File Templates.
	 */
	class ShopExcelParser {

		private $inTable;
		private $lastRowDetected;
		private $currentTable;
		private $tableDao;
		private $message;
		private $tableCount;
		private $firstDataRow;

		private $languageCount;
		private $dataColumnCount;

		const HEADER_COLUMN_COUNT = 3;
		const DATA_COLUMN_COUNT_BASE = 4;
		const DATA_COLUMN_COUNT_PER_LANGUAGE = 3;
		const FIRST_HEADER_ROW = 2;

		const CONSTANT_ROW = 1;
		const RESIDENT_COUNT_COL = 1;
		const WORKING_COUNT_COL = 2;
		const TOTAL_EXPEDITURES_COL = 3;
		const PER_CAPTIVA_TAX_COL = 4;
		const LAST_CONFIG_COL = self::PER_CAPTIVA_TAX_COL;

		public function parseExcel($filePath, $fileName, $worksheetName) {
			$started = time();
			$this->tableCount = 0;
			$this->message = "";
			$excelFile = new XLSXReader($filePath);
			$this->message .= "Processing file: " . $fileName . "\n";
			$languages = LanguageHelper::getLanguages();
			$this->languageCount = count($languages);

			$this->dataColumnCount = $this->languageCount * self::DATA_COLUMN_COUNT_PER_LANGUAGE + self::DATA_COLUMN_COUNT_BASE;
			$this->firstDataRow = $this->languageCount + self::FIRST_HEADER_ROW;

			$worksheet = null;
			foreach ($excelFile->getSheets() as $candidateWorksheet) {
				if (strcmp(trim($worksheetName), trim($candidateWorksheet->getName())) == 0) {
					$worksheet = $candidateWorksheet;
					break;
				}
			}
			if ($worksheet !== null) {
				$this->parseWorksheet($worksheet);
				$this->message .= "\n File processed in: " . (time() - $started) . " seconds.";
				$this->message .= "\n Tables found: " . $this->tableCount;
			} else {
				$this->message .= "\n <span style='color:red;'>Error: sheet 'Current' not found in the excel.</span>";
			}
			return $this->message;
		}

		private function parseWorksheet(XLSXReaderSheet $worksheet) {
			$this->tableDao->deleteAll();
			$this->lastRowDetected = false;
			$this->currentTable = array();
			foreach ($worksheet->getRowIterator() as $rowNum => $row) {
				$this->parseRow($rowNum, $row);
				if ($this->lastRowDetected) {
					break;
				}
			}
		}

		private function parseRow($rowIndex, XLSXReaderRowIterator $rowIterator) {
			if ($rowIndex == self::CONSTANT_ROW) {
				$this->parseConstants($rowIterator);
			} else if (($rowIndex >= self::FIRST_HEADER_ROW) && ($rowIndex < $this->firstDataRow)) {
				array_push($this->currentTable, $this->getDataForCurrentRow($rowIterator, $rowIndex));
			} else if ($rowIndex >= $this->firstDataRow) {
				if ($rowIndex == $this->firstDataRow) {
					// save table header
					$this->tableDao->save($this->currentTable);
				}
				$currentRow = array();
				foreach ($rowIterator->getCellIterator() as $colNum => $cell) {
					if ($colNum < $this->dataColumnCount) {
						if ($this->isTableBegin($colNum, $cell)) {
							if ($this->inTable) {
								$this->tableDao->save($this->currentTable);
								$this->tableCount++;
							} else {
								$this->inTable = true;
							}
							$this->currentTable = array();
							array_push($currentRow, $cell);
						} else {
							$this->detectLastRow($colNum, $cell);
							if ($this->lastRowDetected) {
								$this->tableCount++;
								$this->tableDao->save($this->currentTable);
								unset($currentRow);
							} else {
								if ($cell != null) {
									array_push($currentRow, $cell);
								}
							}
						}
					}
				}
				if (isset($currentRow)) {
					array_push($this->currentTable, $currentRow);
				}
			}
		}


		private function detectLastRow($colNum, $cell) {
			$this->lastRowDetected = $colNum == 0 && isset($cell) && (strcmp($cell, "#END") == 0);
		}

		private function isTableBegin($colNum, $cell) {
			return $colNum == 0 && isset($cell) && (strlen($cell) != 0);
		}

		private function getDataForCurrentRow(XLSXReaderRowIterator $rowIterator) {
			$data = array();
			foreach ($rowIterator->getCellIterator() as $cellValue) {
				if ($cellValue != null) {
					array_push($data, $cellValue);
				}
			}
			return $data;
		}

		public function setTableDao(ShopTableDao $tableDao) {
			$this->tableDao = $tableDao;
		}

		private function parseConstants(XLSXReaderRowIterator $rowIterator) {
			$residentCount = 0;
			$workingCount = 0;
			$totalExpeditures = 0;
			$perCaptivaTax = 0;
			foreach ($rowIterator->getCellIterator() as $colNum => $cell) {
				switch ($colNum) {
					case self::RESIDENT_COUNT_COL:
						$residentCount = $cell;
						break;
					case self::WORKING_COUNT_COL:
						$workingCount = $cell;
						break;
					case self::TOTAL_EXPEDITURES_COL:
						$totalExpeditures = $cell;
						break;
					case self::PER_CAPTIVA_TAX_COL:
						$perCaptivaTax = $cell;
						break;
				}
			}
			$this->tableDao->saveConstants($workingCount, $residentCount, $totalExpeditures, $perCaptivaTax);
		}
	}
